#include "scene.h"

void Scene::setCameraPos(const glm::vec2 &pos) {
    camera_pos_ = pos;
    camera_pos_ = glm::clamp(camera_pos_, glm::vec2(-30), world_size_ - game_.getScreenSize() + glm::vec2(30));
    // 限制在边界内
}

void Scene::addChild(Object *child) {
    switch (child->getType()) {
        case ObjectType::OBJECT_SCREEN:
            children_screen_.push_back(dynamic_cast<ObjectScreen *>(child));
            break;
        case ObjectType::OBJECT_WORLD:
        case ObjectType::ENEMY:
            children_world_.push_back(dynamic_cast<ObjectWorld *>(child));
            break;
        default:
            children_.push_back(child); // 添加到父类对象列表
            break;
    }
}

void Scene::removeChild(Object *child) {
    switch (child->getType()) {
        case ObjectType::OBJECT_SCREEN:
            children_screen_.erase(std::remove(children_screen_.begin(), children_screen_.end(), child),
                                   children_screen_.end());
            break;
        case ObjectType::OBJECT_WORLD:
        case ObjectType::ENEMY:
            children_world_.erase(std::remove(children_world_.begin(), children_world_.end(), child),
                                  children_world_.end());
            break;
        default:
            children_.erase(std::remove(children_.begin(), children_.end(), child), children_.end()); // 从父类对象列表中移除
            break;
    }
}

bool Scene::handleEvents(SDL_Event &event) {
    for (auto child: children_screen_) {
        if (child->getActive()) {
            if (child->handleEvents(event)) {
                return true;
            }
        }
    }
    if (is_paused_) {
        return false;
    }
    Object::handleEvents(event); // 处理父类事件
    for (auto child: children_world_) {
        if (child->getActive()) {
            if (child->handleEvents(event)) {
                return true;
            }
        }
    }
    return false;
}

void Scene::update(float dt) {
    if (!is_paused_) {
        Object::update(dt);
        for (auto it = children_world_.begin(); it != children_world_.end();) {
            auto child = *it;
            if (child->getNeedRemove()) {
                it = children_world_.erase(it);
                child->clean();
                delete child;
                child = nullptr;
                SDL_Log("Scene: remove world child!");
            } else {
                if (child->getActive()) {
                    child->update(dt);
                }
                ++it;
            }
        }
    }
    for (auto it = children_screen_.begin(); it != children_screen_.end();) {
        auto child = *it;
        if (child->getNeedRemove()) {
            it = children_screen_.erase(it);
            child->clean();
            delete child;
            child = nullptr;
        } else {
            if (child->getActive()) {
                child->update(dt);
            }
            ++it;
        }
    }
}

void Scene::render() {
    Object::render(); // 渲染父类

    for (auto child: children_world_) {
        if (child->getActive()) {
            child->render(); // 渲染事件
        }
    }
    for (auto child: children_screen_) {
        if (child->getActive()) {
            child->render(); // 渲染事件
        }
    }
}

void Scene::clean() {
    Object::clean(); // 清理父类
    for (auto child: children_screen_) {
        child->clean(); // 清理事件
    }
    children_screen_.clear(); // 清理事件
    for (auto child: children_world_) {
        child->clean(); // 清理事件
    }
    children_world_.clear(); // 清理事件
}
